/* 
 *   Date       Developer   Description
 *   
 *
 *   Classname:  zzz.developers.SpringRoute.services.Utils
 * 
 *   Date:   2014-3-12
 * 
 *   The source code contained in this listing is proprietary to
 *   HLJ POST YITONG INFO-NET CO.,LTD.
 * 
 *   Unauthorized copying, adaptation, distribution, use, or display
 *   is strictly prohibited.
 *   This software is Copyright 2014 HLJ POST YITONG INFO-NET CO.,LTD.
 */
package com.titan.demo.camel.developers.SpringRoute.services;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import org.apache.camel.CamelContext;
import org.apache.camel.spring.SpringCamelContext;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.titan.core.utils.data.StringUtils;



/**
 *
 *
 * @author Administrator
 *
 */
public class Utils {
    private static ClassPathXmlApplicationContext actx = null;
    private static BeanFactory factory = null;
    
    
    public static synchronized void init(String[] paths) {
        if(actx==null) {
            actx = new ClassPathXmlApplicationContext();
            actx.setConfigLocations(paths);
            actx.refresh();
        }
        if(factory==null) {
            factory = actx.getBeanFactory();
        }
    }
    public static <T> T getBean(String beanid, Class<T> requiredType) throws BeansException {
        return factory.getBean(beanid, requiredType);
    }
    public static Object getBean(String beanid) throws BeansException {
        return factory.getBean(beanid);
    }
    public static Object invoke(String beanid, String method, Object[] args) throws Exception {
        Object object = getBean(beanid);
        if (object != null) {
            Class[] argsClass = null;
            if (args != null) {
                argsClass = new Class[args.length];
                for (int i = 0; i < argsClass.length; i++) {
                    argsClass[i] = args[i] == null ? null : args[i].getClass();
                }
            }
            Method methodhandle = findClass(object).getMethod(method, argsClass);
            return methodhandle.invoke(object, args);
        }
        return null;
    }
    public static Object invoke(String beanid, String method) throws Exception {
        Object object = getBean(beanid);
        if (object != null) {
            Method methodhandle = findClass(object).getMethod(method);
            return methodhandle.invoke(object);
        }
        return null;
    }
    
    public static Map<String, CamelContext> getCamelContext() {
        Map<String, SpringCamelContext> map = actx.getBeansOfType(SpringCamelContext.class);
        Set<Map.Entry<String, SpringCamelContext>> entries = map.entrySet();
        Map<String, CamelContext> answer = new HashMap<String, CamelContext>();
        for (Map.Entry<String, SpringCamelContext> entry : entries) {
            String name = entry.getKey();
//            System.out.println(">>> "+name+"  #################################");
            CamelContext camelContext = entry.getValue();
//            System.out.println(camelContext);
            answer.put(name, camelContext);
        }
        return answer;
    }
    public static CamelContext getCamelContext(String name) {
        Map<String, CamelContext> map = getCamelContext();
        return map.get(name);
    }
    
    
    public static void out(Class clazz, String method) {
        out(clazz, method, null);
    }
    public static void out(Class clazz, String method, String info) {
        StringBuffer buf = new StringBuffer(512);
        buf.append("执行类[").append(clazz.getSimpleName()).append("]");
        buf.append("的方法[").append(method).append("]");
        if(StringUtils.isNotEmpty(info)) {
            buf.append(" >> ").append(info);
        } else {
        }
        buf.append("。");
        
        System.out.println(buf.toString());
    }
    public static void sleep(long timeMillis) {
        try {
            Thread.sleep(timeMillis);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    
    public static void async(int thread, Runnable...items) {
        ExecutorService exec = Executors.newFixedThreadPool(thread);
        try {
            for (Runnable run : items) {
                exec.execute(run);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            exec.shutdown();
        }        
    }
    public static void parallel(int thread, Runnable...items) {
        List<Future> futureList = new ArrayList<Future>();
        
        ExecutorService exec = Executors.newFixedThreadPool(thread);
        try {
            for (Runnable run : items) {
                futureList.add(exec.submit(run));
            }
            
            for (Future<Object> future : futureList) {
                future.get();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            exec.shutdown();
        }        
    }
    public static void run(Runnable runnable) {
        ExecutorService exec = Executors.newSingleThreadExecutor();
        try {
            exec.execute(runnable);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            exec.shutdown();
        }        
    }
    public static Runnable create(final String beanid, final String method, final Object[] args) {
        return new Runnable() {
            public void run() {
                try {
                    Utils.invoke(beanid, method, args);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        };
    }
    


    private static Class findClass(Object object) {
        Class classname = null;
        if (object.getClass().isAssignableFrom(java.lang.Class.class)) {
            classname = (Class) object;
        } else {
            classname = object.getClass();
        }
        return classname;
    }
}

